package org.example.erat.view;

import org.example.erat.controller.EratController;
import org.example.erat.model.ReportAnalyzer;
import org.example.erat.model.Student;
import org.example.erat.visualization.ChartGenerator;
import org.example.erat.visualization.EChartsImplementor;
import org.example.erat.visualization.JFreeChartImplementor;
import org.example.erat.visualization.LineChartGenerator;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.List;
import java.util.Map;

public class SwingView extends JFrame implements View {
    private static final long serialVersionUID = 1L;
    private EratController controller;
    private JTextArea logArea;
    private DefaultTableModel studentTableModel;
    private DefaultTableModel missingReportTableModel;
    private DefaultTableModel experimentTableModel;
    private JTable studentTable;
    private JTable missingReportTable;
    private JTable experimentTable;
    private JButton importStudentsBtn;
    private JButton analyzeReportsBtn;
    private JButton exportStatisticsBtn;
    private JButton showChartBtn;
    private JFileChooser fileChooser;
    private JLabel statusLabel;
    private ReportAnalyzer reportAnalyzer;

    public SwingView() {
        initUI();
        fileChooser = new JFileChooser();
        fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
    }

    private void initUI() {
        setTitle("实验报告统计分析工具(ERAT)");
        setSize(1000, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 创建主面板
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
        setContentPane(mainPanel);

        // 创建顶部按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10));
        mainPanel.add(buttonPanel, BorderLayout.NORTH);

        importStudentsBtn = new JButton("导入学生信息");
        analyzeReportsBtn = new JButton("分析实验报告");
        exportStatisticsBtn = new JButton("导出统计数据");
        showChartBtn = new JButton("显示提交率图表");

        buttonPanel.add(importStudentsBtn);
        buttonPanel.add(analyzeReportsBtn);
        buttonPanel.add(exportStatisticsBtn);
        buttonPanel.add(showChartBtn);

        // 创建标签页面板
        JTabbedPane tabbedPane = new JTabbedPane();
        mainPanel.add(tabbedPane, BorderLayout.CENTER);

        // 学生信息表
        studentTableModel = new DefaultTableModel(
                new String[]{"学号", "姓名", "年级", "专业"}, 0);
        studentTable = new JTable(studentTableModel);
        JScrollPane studentScrollPane = new JScrollPane(studentTable);
        tabbedPane.addTab("学生信息", studentScrollPane);

        // 缺交报告表
        missingReportTableModel = new DefaultTableModel(
                new String[]{"学号", "姓名", "缺交次数", "缺交实验列表"}, 0);
        missingReportTable = new JTable(missingReportTableModel);
        JScrollPane missingReportScrollPane = new JScrollPane(missingReportTable);
        tabbedPane.addTab("缺交报告统计", missingReportScrollPane);

        // 实验统计信息表
        experimentTableModel = new DefaultTableModel(
                new String[]{"实验编号", "应交人数", "已交人数", "缺交人数", "缺交学生列表"}, 0);
        experimentTable = new JTable(experimentTableModel);
        JScrollPane experimentScrollPane = new JScrollPane(experimentTable);
        tabbedPane.addTab("实验统计信息", experimentScrollPane);

        // 创建日志面板
        JPanel logPanel = new JPanel(new BorderLayout());
        logPanel.setBorder(BorderFactory.createTitledBorder("操作日志"));
        logArea = new JTextArea(10, 10);
        logArea.setEditable(false);
        JScrollPane logScrollPane = new JScrollPane(logArea);
        logPanel.add(logScrollPane, BorderLayout.CENTER);
        mainPanel.add(logPanel, BorderLayout.SOUTH);

        // 底部状态栏
        statusLabel = new JLabel("就绪");
        mainPanel.add(statusLabel, BorderLayout.SOUTH);

        // 添加按钮事件监听器
        importStudentsBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                importStudents();
            }
        });

        analyzeReportsBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                analyzeReports();
            }
        });

        exportStatisticsBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                exportStatistics();
            }
        });

        showChartBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showSubmissionRateChart();
            }
        });
    }

    private void importStudents() {
        fileChooser.setDialogTitle("选择学生信息文件");
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int result = fileChooser.showOpenDialog(this);

        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            String format = getFileFormat(selectedFile.getName());
            if (format == null) {
                showMessage("错误", "不支持的文件格式，请选择Excel或CSV文件");
                return;
            }

            try {
                statusLabel.setText("正在导入学生信息...");
                controller.importStudents(selectedFile, format);
                statusLabel.setText("学生信息导入完成");
            } catch (Exception ex) {
                statusLabel.setText("导入失败");
                showError("导入失败: " + ex.getMessage());
                log("错误: " + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }

    private void analyzeReports() {
        fileChooser.setDialogTitle("选择实验报告目录");
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int result = fileChooser.showOpenDialog(this);

        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedDirectory = fileChooser.getSelectedFile();
            try {
                statusLabel.setText("正在分析实验报告...");
                controller.analyzeReports(selectedDirectory.getAbsolutePath());
                statusLabel.setText("实验报告分析完成");
            } catch (Exception ex) {
                statusLabel.setText("分析失败");
                showError("分析失败: " + ex.getMessage());
                log("错误: " + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }

    private void exportStatistics() {
        fileChooser.setDialogTitle("选择导出位置");
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int result = fileChooser.showSaveDialog(this);

        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedDirectory = fileChooser.getSelectedFile();
            String format = (String) JOptionPane.showInputDialog(
                    this,
                    "选择导出格式:",
                    "导出统计数据",
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    new String[]{"Excel", "CSV"},
                    "Excel");

            if (format != null) {
                try {
                    statusLabel.setText("正在导出统计数据...");
                    controller.exportStatistics(selectedDirectory, format.toLowerCase());
                    statusLabel.setText("统计数据导出完成");
                    showMessage("成功", "统计数据已成功导出到: " + selectedDirectory.getAbsolutePath());
                } catch (Exception ex) {
                    statusLabel.setText("导出失败");
                    showError("导出失败: " + ex.getMessage());
                    log("错误: " + ex.getMessage());
                    ex.printStackTrace();
                }
            }
        }
    }

    private void showSubmissionRateChart() {
        try {
            if (reportAnalyzer == null || reportAnalyzer.getSubmissionRates().isEmpty()) {
                showMessage("提示", "没有足够的数据生成图表，请先导入学生信息并分析实验报告");
                return;
            }

            statusLabel.setText("正在生成提交率图表...");

            // 创建图表生成器
            ChartGenerator chartGenerator = new LineChartGenerator(new JFreeChartImplementor());
            chartGenerator.generateSubmissionRateChart(reportAnalyzer);

            statusLabel.setText("图表生成完成");
        } catch (Exception ex) {
            statusLabel.setText("图表生成失败");
            showError("图表生成失败: " + ex.getMessage());
            log("错误: " + ex.getMessage());
            ex.printStackTrace();
        }
    }

    private String getFileFormat(String fileName) {
        if (fileName.toLowerCase().endsWith(".xlsx") || fileName.toLowerCase().endsWith(".xls")) {
            return "excel";
        } else if (fileName.toLowerCase().endsWith(".csv")) {
            return "csv";
        }
        return null;
    }

    private void log(String message) {
        logArea.append(message + "\n");
        logArea.setCaretPosition(logArea.getDocument().getLength());
    }

    @Override
    public void setController(EratController controller) {
        this.controller = controller;
    }

    @Override
    public void displayStudents(List<Student> students) {
        SwingUtilities.invokeLater(() -> {
            studentTableModel.setRowCount(0);

            if (students == null || students.isEmpty()) {
                log("警告: 导入的学生列表为空");
                showMessage("提示", "未找到有效的学生数据");
                return;
            }

            for (Student student : students) {
                studentTableModel.addRow(new Object[]{
                        student.getStudentId(),
                        student.getName(),
                        student.getGrade(),
                        student.getMajor()
                });
            }

            log("已成功导入 " + students.size() + " 名学生信息");
        });
    }

    @Override
    public void displayMissingReports(Map<String, List<String>> missingReports) {
        SwingUtilities.invokeLater(() -> {
            missingReportTableModel.setRowCount(0);

            if (missingReports == null || missingReports.isEmpty()) {
                log("提示: 没有发现缺交报告");
                showMessage("提示", "所有学生的实验报告均已提交");
                return;
            }

            for (Map.Entry<String, List<String>> entry : missingReports.entrySet()) {
                String studentId = entry.getKey();
                List<String> missingExperiments = entry.getValue();

                // 获取学生姓名
                String studentName = "";
                for (int i = 0; i < studentTableModel.getRowCount(); i++) {
                    if (studentTableModel.getValueAt(i, 0).equals(studentId)) {
                        studentName = (String) studentTableModel.getValueAt(i, 1);
                        break;
                    }
                }

                missingReportTableModel.addRow(new Object[]{
                        studentId,
                        studentName,
                        missingExperiments.size(),
                        String.join(", ", missingExperiments)
                });
            }

            log("已分析缺交报告数据，共发现 " + missingReports.size() + " 名学生有缺交记录");
        });
    }

    @Override
    public void displayExperimentStatistics(Map<String, List<String>> experimentStatistics) {
        SwingUtilities.invokeLater(() -> {
            experimentTableModel.setRowCount(0);

            if (experimentStatistics == null || experimentStatistics.isEmpty()) {
                log("警告: 实验统计数据为空");
                showMessage("提示", "没有找到实验报告数据");
                return;
            }

            // 获取学生总数
            int totalStudents = studentTableModel.getRowCount();

            // 添加实验统计数据
            for (Map.Entry<String, List<String>> entry : experimentStatistics.entrySet()) {
                String experimentName = entry.getKey();
                List<String> stats = entry.getValue();

                int missingCount = Integer.parseInt(stats.get(0));
                int submittedCount = totalStudents - missingCount;

                experimentTableModel.addRow(new Object[]{
                        experimentName,
                        totalStudents,
                        submittedCount,
                        missingCount,
                        stats.get(1)
                });
            }

            log("已完成实验统计分析，共分析 " + experimentStatistics.size() + " 个实验");
        });
    }

    @Override
    public void setReportAnalyzer(ReportAnalyzer reportAnalyzer) {
        this.reportAnalyzer = reportAnalyzer;
    }

    @Override
    public void showMessage(String message) {
        SwingUtilities.invokeLater(() -> {
            JOptionPane.showMessageDialog(this, message, "消息", JOptionPane.INFORMATION_MESSAGE);
            log(message);
        });
    }

    @Override
    public void showMessage(String title, String message) {
        SwingUtilities.invokeLater(() -> {
            JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
            log("[" + title + "] " + message);
        });
    }

    @Override
    public void showError(String message) {
        SwingUtilities.invokeLater(() -> {
            JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE);
            log("错误: " + message);
        });
    }

    @Override
    public void startApplication() {
        SwingUtilities.invokeLater(() -> {
            setVisible(true);
            log("实验报告统计分析工具已启动");
        });
    }
}